/*
airplane game
https://zhuanlan.zhihu.com/p/24697687?refer=c2game

<conio.h>
    c = getch();  get user's input, without Enter
    kbhit()   whether there is input
*/

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>

int posx, posy;        // airplane
int bulletx, bullety;  // bullet
int enemyx, enemyy;    // enemy
int high, width;       // display
int score;
int life;


void HideCursor()
{
    CONSOLE_CURSOR_INFO cursor_info = {1, 0};
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}


void gotoxy(int x, int y)
{
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD pos;
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(handle, pos);
}

void startup()
{
    high = 20;
    width = 30;

    posx = high / 2;
    posy = width / 2;

    bulletx = 0;
    bullety = posy;

    enemyx = 0;
    enemyy = posy;

    score = 0;
    life = 3;
}


void show()
{
    gotoxy(0, 0);
    int i, j;
    for(i=0; i<high; i++)
    {
        for(j=0; j<width; j++)
        {
            if(i == posx && j == posy)
                printf("*");
            else if(i == enemyx && j == enemyy)
                printf("@");
            else if(i == bulletx && j == bullety)
                printf("o");
            else
                printf(" ");
        }
        printf("\n");
    }
    printf("SCORE: %d\tLIFE: %d\n", score, life);

}


void updateWithoutInput()
{
    if(bulletx > -1)
        bulletx--;

    if(bulletx == enemyx && bullety == enemyy)
    {
        score++;
        enemyx = -1;     // generate new enemy
        enemyy = rand() % width;
        bulletx = -2;
    }
    else if(enemyx == posx && enemyy == posy)
    {
        posx = rand() % high;
        posy = rand() % width;
        life--;
    }

    static int speed = 0;
    if(speed < 10)
        speed++;
    if(speed == 10)
    {
        speed = 0;
        enemyx++;
    }

    if(enemyx > high)
    {
        enemyx = 0;
        enemyy = rand() % width;
    }
    posx = posx < 1 ? 1 : posx;
    posx = posx >= high ? high-1 : posx;
    posy = posy < 1 ? 1 : posy;
    posy = posy >= width ? width-1: posy;
}


void updateWithInput()
{
    char control;
    if(kbhit())   // whether there is an input
    {
        control = getch();   // user input(awsd) to control airplane position
        switch(control)
        {
            case 'a':
                posy--;
                break;
            case 'd':
                posy++;
                break;
            case 'w':
                posx--;
                break;
            case 's':
                posx++;
                break;
            case ' ':
            {
                bulletx = posx - 1;
                bullety = posy;
            }
        }
    }
}


int main()
{
    startup();
    while(1)
    {
        show();
        updateWithoutInput();
        updateWithInput();
        HideCursor();
    }

    return 0;
}
